<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Javascript tests</title>
  <link rel="stylesheet" href="qunit-2.0.1.css">
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture">
    <form id="id_item_form">
      <input name="text" />
      <input type="hidden" name="csrfmiddlewaretoken" value="tokey" />
      <div class="has-error">
        <div class="help-block">
          Error text
        </div>
      </div>
    </form>

    <table id="id_list_table">
    </table>
  </div>

  <script src="../jquery-3.1.1.min.js"></script>
  <script src="../list.js"></script>
  <script src="qunit-2.0.1.js"></script>
  <script src="sinon-1.17.6.js"></script>

  <script>
/* global sinon */

QUnit.test("errors should be hidden on keypress", function (assert) {
  window.Superlists.initialize();
  $('input[name="text"]').trigger('keypress');
  assert.equal($('.has-error').is(':visible'), false);
});

QUnit.test("errors aren't hidden if there is no keypress", function (assert) {
  window.Superlists.initialize();
  assert.equal($('.has-error').is(':visible'), true);
});


var server, sandbox;
QUnit.testStart(function () {
  server = sinon.fakeServer.create();
  sandbox = sinon.sandbox.create();
});
QUnit.testDone(function () {
  server.restore();
  sandbox.restore();
});

QUnit.test("should call updateItems on initialize", function (assert) {
  var params = {
    listApiUrl: '/list/api/x/',
    itemsApiUrl: '/items/api/url/',
    listId: 7
  };
  sandbox.spy(window.Superlists, 'updateItems');
  window.Superlists.initialize(params);
  assert.equal(
    window.Superlists.updateItems.lastCall.args,
    params.listApiUrl
  );
});

QUnit.test("updateItems should get correct url by ajax", function (assert) {
  var url = '/given/api/url';
  window.Superlists.updateItems(url);

  assert.equal(server.requests.length, 1);
  var request = server.requests[0];
  assert.equal(request.url, url);
  assert.equal(request.method, 'GET');
});

QUnit.test("updateItems should fill in lists table from ajax response", function (assert) {
  var url = '/given/api/url';
  var responseData = {id: 7, items: [
    {id: 101, list: 3, text: 'item 1 text'},
    {id: 102, list: 3, text: 'item 2 text'},
  ]};
  server.respondWith('GET', url, [
    200, {"Content-Type": "application/json"}, JSON.stringify(responseData)
  ]);
  window.Superlists.updateItems(url);

  server.respond();

  var rows = $('#id_list_table tr');
  assert.equal(rows.length, 2);
  var row1 = $('#id_list_table tr:first-child td');
  assert.equal(row1.text(), '1: item 1 text');
  var row2 = $('#id_list_table tr:last-child td');
  assert.equal(row2.text(), '2: item 2 text');
});


QUnit.test("should intercept form submit and do ajax post", function (assert) {
  var params = {
    listApiUrl: '/list/api/x/',
    itemsApiUrl: '/items/api/url/',
    listId: 7
  };
  window.Superlists.initialize(params);

  $('#id_item_form input[name="text"]').val('user input');
  $('#id_item_form input[name="csrfmiddlewaretoken"]').val('tokeney');
  $('#id_item_form').submit();

  assert.equal(server.requests.length, 2);
  var request = server.requests[1];
  assert.equal(request.url, params.itemsApiUrl);
  assert.equal(request.method, "POST");
  assert.equal(
    request.requestBody,
    'list=7&text=user+input&csrfmiddlewaretoken=tokeney'
  );
});


QUnit.test("should call updateItems after successful post", function (assert) {
  var params = {
    listApiUrl: '/list/api/x/',
    itemsApiUrl: '/items/api/url/',
    listId: 7
  };
  window.Superlists.initialize(params);
  var response = [
    201,
    {"Content-Type": "application/json"},
    JSON.stringify({}),
  ];
  server.respondWith('POST', params.itemsApiUrl, response);
  $('#id_item_form input[name="text"]').val('user input');
  $('#id_item_form input[name="csrfmiddlewaretoken"]').val('tokeney');
  $('#id_item_form').submit();

  sandbox.spy(window.Superlists, 'updateItems');
  server.respond();

  assert.equal(
    window.Superlists.updateItems.lastCall.args,
    params.listApiUrl
  );
});


QUnit.test("should not intercept form submit if no api url passed in", function (assert) {
  window.Superlists.initialize();
  assert.equal($._data($('#id_item_form')[0], 'events'), undefined);
});


QUnit.test("should display errors on post failure", function (assert) {
  var params = {
    listApiUrl: '/list/api/x/',
    itemsApiUrl: '/items/api/url/',
    listId: 7
  };
  window.Superlists.initialize(params);
  server.respondWith('POST', params.itemsApiUrl, [
    400,
    {"Content-Type": "application/json"},
    JSON.stringify({'text': ['something is amiss']})
  ]);
  $('.has-error').hide();

  $('#id_item_form').submit();
  server.respond(); // post

  assert.equal($('.has-error').is(':visible'), true);
  assert.equal($('.has-error .help-block').text(), 'something is amiss');
});


QUnit.test("should display other errors on post failure", function (assert) {
  var params = {
    listApiUrl: '/list/api/x/',
    itemsApiUrl: '/items/api/url/',
    listId: 7
  };
  window.Superlists.initialize(params);
  server.respondWith('POST', params.itemsApiUrl, [
    400,
    {"Content-Type": "application/json"},
    JSON.stringify({'non_field_errors': ['something else is amiss']})
  ]);
  $('.has-error').hide();

  $('#id_item_form').submit();
  server.respond(); // post

  assert.equal($('.has-error').is(':visible'), true);
  assert.equal($('.has-error .help-block').text(), 'something else is amiss');
});

QUnit.test("should hide errors on post success", function (assert) {
  var params = {
    listApiUrl: '/list/api/x/',
    itemsApiUrl: '/items/api/url/',
    listId: 7
  };
  window.Superlists.initialize(params);
  var response = [
    201,
    {"Content-Type": "application/json"},
    JSON.stringify({}),
  ];
  server.respondWith(response);
  $('.has-error').show();

  $('#id_item_form').submit();
  server.respond(); // post

  assert.equal($('.has-error').is(':visible'), false);
});


QUnit.test("should display generic error if no error json", function (assert) {
  var url = '/listitemsapi/';
  window.Superlists.initialize(url);
  server.respondWith('POST', url, [
    502,
    {},
    ''
  ]);
  $('.has-error help-block').text('old error');
  $('.has-error').hide();

  $('#id_item_form').submit();
  server.respond(); // post

  assert.equal($('.has-error').is(':visible'), true);
  assert.equal(
    $('.has-error .help-block').text(),
    'Error talking to server. Please try again.'
  );
});


  </script>

</body>
</html>

